import { _decorator, CCFloat, Component, director, math, PhysicsSystem2D, Vec2 } from 'cc';
const { ccclass, property, menu } = _decorator;

@ccclass('PlayerDataWithDash')
export class PlayerDataWithDash extends Component {
    // 重力相关参数
    private _gravityStrength: number = 0;
    private _gravityScale: number = 1;

    @property({ group: { name: 'Gravity', displayOrder: 0 },tooltip: '重力强度' })
    fallGravityMult: number = 1.5;

    @property({ group: { name: 'Gravity', displayOrder: 1 },tooltip: '最大下落速度' })
    maxFallSpeed: number = 25;

    @property({ group: { name: 'Gravity', displayOrder: 2 },tooltip: '快速下落时的重力乘数' })
    fastFallGravityMult: number = 2;

    @property({ group: { name: 'Gravity', displayOrder: 3 },tooltip: '快速下落时的最大速度' })
    maxFastFallSpeed: number = 30;

    // 奔跑相关参数
    @property({ group: { name: 'Run', displayOrder: 10 },tooltip: '最大奔跑速度' })
    runMaxSpeed: number = 10;

    @property({ group: { name: 'Run', displayOrder: 11 },tooltip: '加速度' })
    runAcceleration: number = 50;

    private _runAccelAmount: number = 0;

    @property({ group: { name: 'Run', displayOrder: 12 },tooltip: '减速度' })
    runDecceleration: number = 50;

    private _runDeccelAmount: number = 0;

    @property({
        group: { name: 'Run', displayOrder: 13 },
        type: CCFloat,
        min: 0,
        max: 1,
        slide: true,
        tooltip: '空中加速度乘数'
    })
    accelInAir: number = 0.8;

    @property({
        group: { name: 'Run', displayOrder: 14 },
        type: CCFloat,
        min: 0,
        max: 1,
        slide: true,
        tooltip: '空中减速度乘数'
    })
    deccelInAir: number = 0.8;

    @property({ group: { name: 'Run', displayOrder: 15 },tooltip: '是否保持动量' })
    doConserveMomentum: boolean = true;

    // 跳跃相关参数
    @property({ group: { name: 'Jump', displayOrder: 20 },tooltip: '跳跃高度' })
    jumpHeight: number = 3;

    @property({ group: { name: 'Jump', displayOrder: 21 },tooltip: '跳跃到顶点的时间' })
    jumpTimeToApex: number = 0.4;

    private _jumpForce: number = 0;

    @property({ group: { name: 'Jump', displayOrder: 22 },tooltip: '跳跃取消时的重力乘数' })
    jumpCutGravityMult: number = 2;

    @property({
        group: { name: 'Jump', displayOrder: 23 },
        type: CCFloat,
        min: 0,
        max: 1,
        slide: true,
        tooltip: '跳跃顶点附近的重力乘数'
    })
    jumpHangGravityMult: number = 0.5;

    @property({ group: { name: 'Jump', displayOrder: 24 },tooltip: '跳跃顶点附近的时间阈值' })
    jumpHangTimeThreshold: number = 0.5;

    @property({ group: { name: 'Jump', displayOrder: 25 },tooltip: '跳跃顶点附近的加速度乘数' })
    jumpHangAccelerationMult: number = 1.1;

    @property({ group: { name: 'Jump', displayOrder: 26 },tooltip: '跳跃顶点附近的速度乘数' })
    jumpHangMaxSpeedMult: number = 1.1;

    // 墙壁跳跃相关参数
    @property({ group: { name: 'Wall Jump', displayOrder: 30 },tooltip: '墙壁跳跃力' })
    wallJumpForce: Vec2 = new Vec2(10, 15);

    @property({
        group: { name: 'Wall Jump', displayOrder: 31 },
        type: CCFloat,
        min: 0,
        max: 1,
        slide: true,
        tooltip: '墙壁跳跃后的奔跑插值'
    })
    wallJumpRunLerp: number = 0.5;

    @property({
        group: { name: 'Wall Jump', displayOrder: 32 },
        type: CCFloat,
        min: 0,
        max: 1.5,
        slide: true,
        tooltip: '墙壁跳跃时间'
    })
    wallJumpTime: number = 0.2;

    @property({ group: { name: 'Wall Jump', displayOrder: 33 },tooltip: '墙壁跳跃时是否转向' })
    doTurnOnWallJump: boolean = true;

    // 滑墙相关参数
    @property({ group: { name: 'Slide', displayOrder: 40 },tooltip: '滑墙速度' })
    slideSpeed: number = -5;

    @property({ group: { name: 'Slide', displayOrder: 41 },tooltip: '滑墙加速度' })
    slideAccel: number = 30;

    // 辅助参数
    @property({
        group: { name: 'Assists', displayOrder: 50 },
        type: CCFloat,
        min: 0.01,
        max: 0.5,
        slide: true,
        tooltip: '土狼时间'
    })
    coyoteTime: number = 0.1;

    @property({
        group: { name: 'Assists', displayOrder: 51 },
        type: CCFloat,
        min: 0.01,
        max: 0.5,
        slide: true,
        tooltip: '跳跃输入缓冲时间'
    })
    jumpInputBufferTime: number = 0.2;

    // 冲刺相关参数
    @property({ group: { name: 'Dash', displayOrder: 60 },tooltip: '冲刺次数' })
    dashAmount: number = 1;

    @property({ group: { name: 'Dash', displayOrder: 61 },tooltip: '冲刺速度' })
    dashSpeed: number = 20;

    @property({ group: { name: 'Dash', displayOrder: 62 },tooltip: '冲刺时间' })
    dashSleepTime: number = 0.1;

    @property({ group: { name: 'Dash', displayOrder: 63 },tooltip: '冲刺攻击时间' })
    dashAttackTime: number = 0;

    @property({ group: { name: 'Dash', displayOrder: 64 },tooltip: '冲刺结束时间' })
    dashEndTime: number = 0.5;

    @property({ group: { name: 'Dash', displayOrder: 65 },tooltip: '冲刺结束速度' })
    dashEndSpeed: Vec2 = new Vec2(10, 0);

    @property({
        group: { name: 'Dash', displayOrder: 66 },
        type: CCFloat,
        min: 0,
        max: 1,
        slide: true,
        tooltip: '冲刺结束奔跑插值'
    })
    dashEndRunLerp: number = 0.8;

    @property({ group: { name: 'Dash', displayOrder: 67 },tooltip: '冲刺恢复时间' })
    dashRefillTime: number = 1;

    @property({
        group: { name: 'Dash', displayOrder: 68 },
        type: CCFloat,
        min: 0.01,
        max: 0.5,
        slide: true,
        tooltip: '冲刺输入缓冲时间'
    })
    dashInputBufferTime: number = 0.1;

    @property({type: CCFloat, min: 0, tooltip: '时间流速'})
    timeScale: number = 1;

    // 计算属性
    public get gravityStrength(): number {
        return this._gravityStrength;
    }

    public get gravityScale(): number {
        return this._gravityScale;
    }

    public get runAccelAmount(): number {
        return this._runAccelAmount;
    }

    public get runDeccelAmount(): number {
        return this._runDeccelAmount;
    }

    public get jumpForce(): number {
        return this._jumpForce;
    }

    /**
     * 验证并计算所有派生属性
     */
    public validate() {
        // 计算重力强度 (gravity = 2 * jumpHeight / timeToJumpApex^2)
        this._gravityStrength = -(2 * this.jumpHeight) / (this.jumpTimeToApex * this.jumpTimeToApex);

        // 计算重力比例（相对于 Cocos 的重力值）
        // 注意：Cocos 的默认重力值可能需要根据项目设置调整
        // 物理参数换算公式
        // PhysicsSystem2D.instance.gravity = new Vec2(0, -980);
        // console.log('Cocos 默认重力值: ', PhysicsSystem2D.instance.gravity);
        // this._gravityScale = this._gravityStrength / -980; // 假设默认重力为 -980 (Unity 2D 默认值)
        const PIXELS_PER_UNIT = 16; // 1单位=16像素
        this._gravityScale = (this._gravityStrength * PIXELS_PER_UNIT) / PhysicsSystem2D.instance.gravity.y;
        

        // 计算奔跑加速度和减速度
        // 公式: amount = ((1 / Time.fixedDeltaTime) * acceleration) / runMaxSpeed
        // 假设固定时间步长为 0.02s (50 FPS)
        this._runAccelAmount = (60 * this.runAcceleration) / this.runMaxSpeed;
        this._runDeccelAmount = (60* this.runDecceleration) / this.runMaxSpeed;

        // 计算跳跃力 (initialJumpVelocity = gravity * timeToJumpApex)
        this._jumpForce = Math.abs(this._gravityStrength) * this.jumpTimeToApex;

        // 限制参数范围
        this.runAcceleration = math.clamp(this.runAcceleration, 0.01, this.runMaxSpeed);
        this.runDecceleration = math.clamp(this.runDecceleration, 0.01, this.runMaxSpeed);

        // this.tick = this.timeScale;//方法1
        director.getScheduler().setTimeScale(this.timeScale);//方法2
        
        console.log('PlayerData 验证完成');
    }

    /** @zh 游戏速率 */
    private _tick: (dt: number) => void = director.tick;

    /** @zh 设置游戏速率 */
    public set tick(vaule: number) {
        director.tick = (dt: number) => {
            this._tick.call(director, dt * vaule);
        }
    }

    protected start(): void {
        this.validate();
    }
}